﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.Logging;
#if NETFX_CORE
using Windows.UI.Xaml;

#else
using System.Windows;
#endif

namespace StyleMVVM.View
{
	[Obsolete("Use Message.Attach in favor of AttachedEventCommand")]
	public sealed class AttachedEventCommand
	{
		public static object GetCommand(DependencyObject obj)
		{
			return (object)obj.GetValue(InternalCommandProperty);
		}

		public static void SetCommand(DependencyObject obj, object value)
		{
			obj.SetValue(InternalCommandProperty, value);
		}

		public static DependencyProperty CommandProperty
		{
			get { return InternalCommandProperty; }
		}

		// Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
		internal static readonly DependencyProperty InternalCommandProperty =
			DependencyProperty.RegisterAttached("Command",
			                                    typeof(object),
			                                    typeof(AttachedEventCommand),
			                                    new PropertyMetadata(null, CommandChanged));

		private static void CommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			processCommandAndEventChange(d);
		}

		public static string GetEvent(DependencyObject obj)
		{
			return (string)obj.GetValue(InternalEventProperty);
		}

		public static void SetEvent(DependencyObject obj, string value)
		{
			obj.SetValue(InternalEventProperty, value);
		}

		public static DependencyProperty EventProperty
		{
			get { return InternalEventProperty; }
		}

		// Using a DependencyProperty as the backing store for Event.  This enables animation, styling, binding, etc...
		internal static readonly DependencyProperty InternalEventProperty =
			DependencyProperty.RegisterAttached("Event",
			                                    typeof(string),
			                                    typeof(AttachedEventCommand),
			                                    new PropertyMetadata(null, EventChanged));

		private static void EventChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			processCommandAndEventChange(d);
		}

		public static object GetParameter(DependencyObject obj)
		{
			return (object)obj.GetValue(InternalParameterProperty);
		}

		public static void SetParameter(DependencyObject obj, object value)
		{
			obj.SetValue(InternalParameterProperty, value);
		}

		public static DependencyProperty ParameterProperty
		{
			get { return InternalParameterProperty; }
		}

		// Using a DependencyProperty as the backing store for Parameter.  This enables animation, styling, binding, etc...
		internal static readonly DependencyProperty InternalParameterProperty =
			DependencyProperty.RegisterAttached("Parameter",
			                                    typeof(object),
			                                    typeof(AttachedEventCommand),
			                                    new PropertyMetadata(null, ParameterChanged));

		private static void ParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			try
			{
				AttachedEventCommandHelper helper = AttachedEventCommandHelper.GetHelper(d);

				if (helper != null)
				{
					helper.Parameter = e.NewValue;
				}
			}
			catch (Exception exp)
			{
				Logger.Error(
					"Excpetion thrown while changing parameter",
					"StyleMVVM.View.AttachedEventCommand",
					exp);
			}
		}

		private static void processCommandAndEventChange(DependencyObject obj)
		{
			try
			{
				object command = GetCommand(obj);
				string eventName = GetEvent(obj);
				object parameter = GetParameter(obj);

				AttachedEventCommandHelper.SetHelper(obj, null);

				if (command != null && !string.IsNullOrEmpty(eventName))
				{
					AttachedEventCommandHelper helper =
						new AttachedEventCommandHelper(command, eventName);

					helper.Parameter = parameter;

					AttachedEventCommandHelper.SetHelper(obj, helper);
				}
			}
			catch (Exception exp)
			{
				Logger.Error(
					"Excpetion thrown while attaching command",
					"StyleMVVM.View.AttachedEventCommand",
					exp);
			}
		}
	}
}